/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package FEMSolver1D;

import FEMShapeFunction1D.FEMShapeFunction1D1;
import Integration.GaussQuadrature;
import Integration.IFunction1D;

/**
 *
 * @author mark_o
 */
public class MatrixGenerator1 implements MatrixGenerator{
    GaussQuadrature gauss;
    FEMShapeFunction1D1 f1;
    FEMShapeFunction1D1 f2;
    double a;
    double b;
    double left;
    double right;

    public MatrixGenerator1(double left, double right) {
        this.left = left;
        this.right = right;
        gauss = new GaussQuadrature(50);
    }

    

    public void setF1(IFunction1D f1) {
        this.f1 = (FEMShapeFunction1D1) f1;
    }

    public void setF2(IFunction1D f2) {
        this.f2 = (FEMShapeFunction1D1) f2;
        getAB();
    }

    private void getAB(){
            a = Math.max(f1.getXi()-f1.getH(), f2.getXi()-f2.getH());
            a = Math.max(a, left);
            b = Math.min(f1.getXi()+f1.getH(), f2.getXi()+f2.getH());
            b = Math.min(right, b);
    }

    public double getKe(final IFunction1D p) {
        if(b<a){
            return 0;
        }
        return gauss.gau(a, b, new IFunction1D() {

            public double calculate(double x) {
                return f1.calculateDerivaty(x)*f2.calculateDerivaty(x)*p.calculate(x);
            }

            public double calculateDerivaty(double x) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        });
    }

    public double getMe(final IFunction1D q) {
        if(b<a){
            return 0;
        }
        return gauss.gau(a, b, new IFunction1D() {

            public double calculate(double x) {
                return f1.calculate(x)*f2.calculate(x)*q.calculate(x);
            }

            public double calculateDerivaty(double x) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        });
    }

    public double getAdv(final IFunction1D w) {
        if(b<a){
            return 0;
        }
        IFunction1D func = new IFunction1D() {

            public double calculate(double x) {
                return f1.calculate(x)*f2.calculateDerivaty(x)*w.calculate(x);
            }

            public double calculateDerivaty(double x) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        };
        return gauss.gau(a, b, func);
    }

    public double getFe(final IFunction1D f) {
            double tmpb = Math.min(right, f1.getXi()+f1.getH());
            double tmpa = Math.max(f1.getXi()-f1.getH(), left);
            IFunction1D func = new IFunction1D() {

            public double calculate(double x) {
                return f.calculate(x)*f1.calculate(x);
            }

            public double calculateDerivaty(double x) {
                throw new UnsupportedOperationException("Not supported yet.");
            }
        };
        return gauss.gau(tmpa, f1.getXi(), func)+gauss.gau(f1.getXi(), tmpb, func);
        //return gauss.gau(tmpa, tmpb, f)*f1.getH();

    }

}
